<?php

namespace nimo\common\models;

use Baum\Node;
use Illuminate\Database\Eloquent\SoftDeletingTrait;
use nimo\common\models\MultiKeyTrait;

class BaseNodeModel extends Node {
    protected $parentColumn = 'node_parent';
    protected $leftColumn = 'node_left';
    protected $rightColumn = 'node_right';
    protected $depthColumn = 'node_depth';
    protected $guarded = array('id','node_parent','node_left','node_right','node_depth');
    protected $scoped = array();

    // protected static $softDeletesEnabled = false|true;
    use SoftDeletingTrait, MultiKeyTrait { MultiKeyTrait::bootSoftDeletingTrait insteadof SoftDeletingTrait;}
    // protected $forceDeleting = false;
    // ------------------------------
    // laravel framework function
    // ------------------------------
    protected function performDeleteOnModel() {
        $trashable = static::softDeletesEnabled() && ! $this->forceDeleting;
        $keys = $this->getKey();
        if (! is_array($keys)) {
            $keys = array($this->getKeyName() => $keys);
        }
        // forever delete
        $query = $this->newQuery();
        foreach ( $keys as $key => $value ) {
            $query = $query->where($key, '=', $value);
        }
        if ($trashable) {
            // soft delete
            $this->{$this->getDeletedAtColumn()} = $time = $this->freshTimestamp();
            return $query->update(array($this->getDeletedAtColumn() => $this->fromDateTime($time)));
        }
        if ($this->forceDeleting) {
            return $query->forceDelete();
        }
        return $query->delete();
    }
    // ------------------------------
    // baum node framework function
    // ------------------------------
    protected function getFreshInstance() {
        $keys = $this->getKey();
        if (! is_array($keys)) {
            return parent::getFreshInstance();
        }
        if ($this->areSoftDeletesEnabled()) {
            $query = static::withTrashed();
            foreach ( $keys as $key => $value ) {
                $query = $query->where($key, '=', $value);
            }
            return $query->first();
        }
        return static::find($this->getKey());
    }
    public function setDepth() {
        $keys = $this->getKey();
        if (! is_array($keys)) {
            return parent::setDepth();
        }
        $self = $this;
        $this->getConnection()->transaction(function () use($self, $keys) {
            $self->reload();
            $level = $self->getLevel();
            $query = $self->newNestedSetQuery();
            foreach ( $keys as $key => $value ) {
                if (! array_key_exists($key, $this->scoped)) {
                    $query = $query->where($key, '=', $value);
                }
            }
            $query->update(array($self->getDepthColumnName() => $level));
            $self->setAttribute($self->getDepthColumnName(), $level);
        });
        return $this;
    }

    /*
     * public function reload() { if ($this->exists || ($this->areSoftDeletesEnabled() && $this->trashed())) { $fresh = $this->getFreshInstance(); if (is_null($fresh)) throw with(new ModelNotFoundException())->setModel(get_called_class()); $this->setRawAttributes($fresh->getAttributes(), true); $this->setRelations($fresh->getRelations()); $this->exists = $fresh->exists; } else { // Revert changes if model is not persisted $this->attributes = $this->original; } return $this; } public function setDepth() { $self = $this; $this->getConnection()->transaction(function () use($self) { $self->reload(); $level = $self->getLevel(); $self->newNestedSetQuery()->where($self->getKeyName(), '=', $self->getKey())->update(array($self->getDepthColumnName() => $level)); $self->setAttribute($self->getDepthColumnName(), $level); }); return $this; }
     */
}

